import 'dart:async';
import 'dart:isolate';

// import 'package:app_links/app_links.dart';
import 'package:app_links/app_links.dart';
import 'package:casdon/app/config/env/common_config.dart';
import 'package:casdon/common/service/tuya_service.dart';
import 'package:casdon/core/logger/log.dart';
import 'package:casdon/core/utils/shared_preferences_utils.dart';
import 'package:casdon/core/utils/toast_utils.dart';
import 'package:casdon/core/utils/wifi/wifi_utils.dart';
import 'package:casdon/modules/device/application/notification/product_category_notifier.dart';
import 'package:casdon/modules/home/application/notification/tuya_auth_notifier.dart';
import 'package:casdon/modules/home/data/model/unified_device_model.dart';
import 'package:casdon/modules/home/providers/home_provider.dart';
import 'package:casdon/auto_router.dart';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class _NFCErrorRecord {
  int count;
  DateTime lastTime;
  _NFCErrorRecord(this.count, this.lastTime);
}

class NFCDeviceDiscoveryController extends StateNotifier<void> {
  final Ref ref;
  StreamSubscription<Uri>? _linkSubscription;
  final List<Uri> _pendingLinks = []; // 待处理的链接队列
  BuildContext? context;

  /// 记录 NFC 标签错误尝试次数和时间
  final Map<String, _NFCErrorRecord> _errorRecords = {};

  NFCDeviceDiscoveryController(this.ref) : super(null) {
    // 先建立监听，但不立即处理
    Log.i("新建：NFCDeviceDiscoveryController");
    _linkSubscription = AppLinks().uriLinkStream.listen((uri) {
      _pendingLinks.add(uri);
      _tryProcessLinks();
    });
  }

  // 在获得context后调用
  void initializeWithContext(BuildContext acontext) {
    context = acontext;
  }

  void _tryProcessLinks() {
    if (context == null || _pendingLinks.isEmpty) return;

    if (_pendingLinks.isEmpty == false) {
      _handleDeepLink(_pendingLinks.last, context!);
    }
  }

  Future<void> _handleDeepLink(Uri uri, BuildContext context) async {
    Log.i('📡 收到深度链接: $uri');
    Log.i('当前线程: ${Isolate.current.debugName ?? Isolate.current.hashCode}');
    if (!_verifyUrl(uri)) {
      Log.w('链接不符合要求，忽略处理');
      return;
    }
    // 1，调用接口/client-product/nfc/deviceBind/checkBind  检测标签是否已绑定
    final checkRet = await ref
        .read(deviceRepositoryProvider)
        .getCheckNfcBind(virtualId: getId(uri)!, pid: getPid(uri)!);
    if ((checkRet?.virtualIdIsExist ?? false) == false) {
      ToastUtil.show("NFC标签不合法");
      return;
    }

    final deviceState = ref.read(unifiedDeviceNotifierProvider);
    List<UnifiedDeviceModel> listModel = deviceState.value?.data ?? [];
    // {"requestId":"0d7983d9-05b7-928c-a9e5-cd4fc756095a","code":200,"msg":"操作成功","data":{"bindState":false,"deviceUuid":"","virtualId":"Ul5L6wCacm2oJQ202509180950000001","virtualIdIsExist":true}}
    if (checkRet?.bindState ?? false) {
      // 已绑定
      // 通过devId查询名下设备
      UnifiedDeviceModel? device;
      try {
        device = listModel.firstWhere((e) => e.uuid == checkRet!.deviceUuid);
      } catch (_) {
        device = null;
      }

      if (device == null) // 没找到
      {
        final vid = checkRet?.deviceUuid;
        if (vid != null) {
          _recordBindError(vid);
        }
        return;
      }
      // 找到设备， 绑定完成后，在线则进入面板，离线则调用接口获取用户设备nfc数据，打开产品说明页面
      if (device.isOnline == true) // 在线，则进入面板
      {
        TuyaService().gotoPanel(
          deviceId: device.devId!,
          pid: device.pid,
          fromType: PanelFromType.nfc,
        );
        return;
      } else {
        // 离线，则查询用户相关数据，进入产品说明页
        final nfcReadMeMap = await ref
            .read(deviceRepositoryProvider)
            .getNFCProductReadMeInfo(deviceId: device.devId!, pid: device.pid);
        if (context.mounted == false) return;
        if (nfcReadMeMap["data"] == null) return;
        final data = nfcReadMeMap["data"]["data"];
        if (data == null) return;
        if (data["url"] != null) {
          WebPageRoute(
            url: data["url"],
            title: data["name"] ?? "",
          ).push(context);
        }
        return;
      }
    } else {
      // 未绑定
      // 通过pid查询名下设备
      UnifiedDeviceModel? device;
      try {
        device = listModel.firstWhere((e) => e.pid == getPid(uri));
      } catch (_) {
        device = null;
      }

      if (device != null) {
        try {
          await ref
              .read(deviceRepositoryProvider)
              .postNfcBind(
                deviceUuid: device.uuid!,
                virtualId: checkRet!.virtualId, //
              );
          ToastUtil.show("NFC标签绑定成功");
        } catch (e) {
          ToastUtil.show("NFC标签绑定失败");
        }
        // 绑定完成后，在线则进入面板，离线则调用接口获取用户设备nfc数据，打开产品说明页面
        if (device.isOnline == true) // 在线，则进入面板
        {
          TuyaService().gotoPanel(
            deviceId: device.devId!,
            pid: device.pid,
            fromType: PanelFromType.nfc,
          );
          return;
        } else {
          // 离线，则查询用户相关数据，进入产品说明页
          final nfcReadMeMap = await ref
              .read(deviceRepositoryProvider)
              .getNFCProductReadMeInfo(
                deviceId: device.devId!,
                pid: device.pid,
              );
          if (context.mounted == false) return;
          if (nfcReadMeMap["data"] == null) return;
          final data = nfcReadMeMap["data"]["data"];
          if (data == null) return;
          if (data["url"] != null) {
            WebPageRoute(
              url: data["url"],
              title: data["name"] ?? "",
            ).push(context);
          }
          return;
        }
      }

      if (device == null) // 没找到， 则进入配网流程
      {
        Log.i('未找到对应设备，进入配网流程');
      }
    }

    // 异步检查登录状态和设备列表
    final isReady = await ref.read(canUseNfcPairnetProvider.future);
    if (!isReady) {
      return;
    }
    Log.i('📡 到深度链接11111: $uri');

    final ssidResult = await WifiUtils.getInstance().getCurrentWifiSsidResult();
    if (!ssidResult.hasPermission) {
      ToastUtil.show("请开启定位权限后再进行配网");
      return;
    }
    final ssid = ssidResult.ssid;
    if (ssid == null) {
      ToastUtil.show("请连接WiFi后再进行配网");
      return;
    }

    final pwd = await checkWifiInfo();
    if (context.mounted == false) return;
    if (pwd == null) {
      WifiConfigRoute(
        pid: getPid(uri)!,
        deviceName: "",
        virtualId: getId(uri)!,
        nextRoute: "add_device_progress",
      ).push(context);
    } else {
      Log.i('当前WiFi SSID: $ssid, 已存储密码，直接进入配网进度页面');
      if (context.mounted == false) return;
      Log.i(
        '119615 paircontroller 当前线程: ${Isolate.current.debugName ?? Isolate.current.hashCode}',
      );

      AddDeviceProgressRoute(
        pid: getPid(uri)!,
        ssid: ssid,
        pwd: pwd,
        deviceName: "",
        virtualId: getId(uri)!,
      ).push(context);
    }
  }

  // 次数检测和自动解绑
  void _recordBindError(String devUUid) async {
    final now = DateTime.now();
    final record = _errorRecords[devUUid];

    if (record == null) {
      // 第一次错误
      _errorRecords[devUUid] = _NFCErrorRecord(1, now);
      ToastUtil.show("NFC标签已经被绑定");
      return;
    }

    final diff = now.difference(record.lastTime);
    if (diff.inSeconds > 10) {
      // 超过 10 秒，重置计数
      _errorRecords[devUUid] = _NFCErrorRecord(1, now);
      ToastUtil.show("NFC标签已经被绑定");
      return;
    }

    // 累计错误次数
    record.count += 1;
    record.lastTime = now;

    if (record.count >= 3) {
      Log.w("⚠️ 检测到 $devUUid 在10秒内连续绑定失败3次，自动执行解绑");
      _errorRecords.remove(devUUid); // 重置防止重复解绑
      await _unbindDevice(devUUid);
    } else {
      ToastUtil.show("NFC标签已经被绑定");
    }
  }

  Future<void> _unbindDevice(String uuid) async {
    try {
      await ref.read(deviceRepositoryProvider).delNfcUnBind(uuid: uuid);
      Log.i("✅ 自动解绑 $uuid 成功");
      ToastUtil.show("NFC标签已自动解绑，请重新绑定");
    } catch (e) {
      Log.e("❌ 自动解绑 $uuid 失败", e, StackTrace.current);
    }
  }

  bool _verifyUrl(Uri uri) {
    if (uri.toString().contains(CommonConfig.nfc_ciot) == false) {
      return false;
    }
    final pid = uri.queryParameters['pid'] ?? "";
    final id = uri.queryParameters['id'] ?? "";
    final c = uri.queryParameters['c'] ?? "";
    final mod = uri.queryParameters['mod'] ?? "";
    if (pid.isEmpty ||
        id.isEmpty ||
        c.isEmpty ||
        mod.isEmpty ||
        mod.toLowerCase() != "nfc") {
      Log.w('参数不完整，忽略处理');
      return false;
    }
    return true;
  }

  String? getPid(Uri uri) {
    if (uri.toString().contains(CommonConfig.nfc_ciot) == false) {
      return null;
    }

    final pid = uri.queryParameters['pid'];
    return pid;
  }

  String? getId(Uri uri) {
    if (uri.toString().contains(CommonConfig.nfc_ciot) == false) {
      return null;
    }
    final id = uri.queryParameters['id'];
    return id;
  }

  String? getC(Uri uri) {
    if (uri.toString().contains(CommonConfig.nfc_ciot) == false) {
      return null;
    }
    final c = uri.queryParameters['c'];
    return c;
  }

  String? getMod(Uri uri) {
    if (uri.toString().contains(CommonConfig.nfc_ciot) == false) {
      return null;
    }
    final mod = uri.queryParameters['mod'];
    return mod;
  }

  Future<String?> checkWifiInfo() async {
    final spUnit = await SPUtils.getInstance();

    final ssidResult = await WifiUtils.getInstance().getCurrentWifiSsidResult();
    if (!ssidResult.hasPermission) {
      ToastUtil.show("请开启定位权限后再尝试");
      return null;
    }
    final ssid = ssidResult.ssid;
    if (ssid == null) {
      // 当前可能不是连接wifi
      return null;
    }

    final pwd = spUnit.getString(ssid);
    if (pwd.isEmpty) {
      // 当前wifi的密码没有存储过
      return null;
    }
    return pwd;
  }

  @override
  void dispose() {
    Log.i("释放：NFCDeviceDiscoveryController");
    _linkSubscription?.cancel();
    super.dispose();
  }
}

final nfcDeviceDiscoveryProvider =
    StateNotifierProvider<NFCDeviceDiscoveryController, void>(
      (ref) => NFCDeviceDiscoveryController(ref),
    );

// 组合登录状态和设备列表加载状态, 涂鸦已经登录且设备列表已经获取(成功或者失败，非加载中)
// 主要用于nfc配网，需要等待设备列表获取完毕后才能开始nfc配网，需要检查是否是自有设备
final canUseNfcPairnetProvider = FutureProvider<bool>((ref) async {
  // 保持 provider 永久存在
  final _ = ref.keepAlive();

  // 当 provider 被销毁前，你可以手动关闭 link
  // 这里一般不需要手动关闭，永久保持即可

  final isLoggedIn = ref.watch(tuyaLoginStateProvider);
  final deviceState = ref.watch(unifiedDeviceNotifierProvider);

  return isLoggedIn &&
      deviceState.maybeWhen(data: (_) => true, orElse: () => false);
});
